#coding:utf-8

import time
import webapp2_extras.appengine.auth.models

from google.appengine.ext import ndb

from webapp2_extras import security

class User(webapp2_extras.appengine.auth.models.User):
    def set_password(self, raw_password):
        """Sets the password for the current user

        :param raw_password:
                The raw password which will be hashed and stored
        """
        self.password = security.generate_password_hash(raw_password, length=12)

    @classmethod
    def get_by_auth_token(cls, user_id, token, subject='auth'):
        """Returns a user object based on a user ID and token.

        :param user_id:
                The user_id of the requesting user.
        :param token:
                The token string to be verified.
        :returns:
                A tuple ``(User, timestamp)``, with a user object and
                the token timestamp, or ``(None, None)`` if both were not found.
        """
        token_key = cls.token_model.get_key(user_id, subject, token)
        user_key = ndb.Key(cls, user_id)
        # Use get_multi() to save a RPC call.
        valid_token, user = ndb.get_multi([token_key, user_key])
        if valid_token and user:
            timestamp = int(time.mktime(valid_token.created.timetuple()))
            return user, timestamp

        return None, None
    
class SiteInfo(ndb.Model):
    """
       网站信息 
    """
    site = ndb.StringProperty()
    version = ndb.StringProperty()
    ItemInfo = ndb.StringProperty()
    
    @classmethod
    def get_key(cls, site):
        return ndb.Key(cls, "%s.%s" %(site, 'ItemInfo'))
    
    @classmethod
    def create_SiteInfo(cls, **kwargs):
        if 'site' not in kwargs:
            return None
        if 'ItemInfo' not in kwargs:
            return None
        
        key = cls.get_key(kwargs['site'])
        af = key.get()
        if af is not None:
            #已经有了
            af.populate(**kwargs)
        else:
            #new one
            af = cls(key=key,
                       **kwargs)
        af.put_async()
        
    @classmethod
    def query_AllSiteInfo(cls):
        return cls.query().fetch()
    
class aForm(ndb.Model):
    """
        单个订单信息
    """
    site = ndb.StringProperty()
    store = ndb.StringProperty()
    name = ndb.StringProperty()
    totalprice = ndb.IntegerProperty()
    price = ndb.IntegerProperty()
    link = ndb.StringProperty()
    time = ndb.StringProperty()
    carriage = ndb.IntegerProperty()
    volume = ndb.IntegerProperty()    
    
    @classmethod
    def get_key(cls, site, name):
        return ndb.Key(cls, "%s.%s" %(site, name), parent = FormInfo.get_key(name))
    
    @classmethod
    def create_aForm(cls, formname, **kwargs):
        if 'name' not in kwargs:
            return None
        
        if 'site' not in kwargs:
            return None
        
        key = cls.get_key(kwargs['site'], formname)
        af = key.get()
        if af is not None:
            #已经有了
            af.populate(**kwargs)
            return af
        else:
            #new one
            return cls(key=key,
                       **kwargs)
        
    @classmethod
    def query_Forms(cls, name):
        return cls.query(ancestor=FormInfo.get_key(name))
    
class FormInfo(ndb.Model):
    """
        订单管理信息
    """
    name = ndb.StringProperty()
    minprice = ndb.IntegerProperty()
    
    @classmethod
    def get_key(cls, name):
        return ndb.Key(cls, name.upper())

    @classmethod
    def get_formInfo(cls, name):
        return cls.get_key(name).get()
    
    @classmethod
    def create_formInfo(cls, name, mp):
        key = cls.get_key(name)
        entity = cls(key=key, name=name, minprice=mp)
        entity.put_async()
        
    @classmethod
    def put_aForm(cls, form):
#         key = cls.get_key(name)
#         form.populate(parent=key)  
        form.put_async()
     
    
#用户关注信息
class UserWatch(ndb.Model):
    userkey = ndb.KeyProperty(kind=User)
    formkey = ndb.KeyProperty(kind=FormInfo)
    
    @classmethod
    def get_key(cls, ukey, fkey):
        return ndb.Key(cls, "%s.%s" %(str(ukey), str(fkey)))
    
    @classmethod
    def add_watch(cls, user, form):
        ukey = ndb.Key(User, user.get_id())
        fkey = form._key
        key  = cls.get_key(ukey, fkey)
        uw = key.get()
        if uw is None:
            uw = UserWatch(key=key,
                           userkey = ukey, 
                           formkey = fkey)
            uw.put()
                        
    @classmethod
    def del_watch(cls, user, form):
        ukey = ndb.Key(User, user.get_id())
        fkey = form._key
        cls.get_key(ukey, fkey).delete()
        
    @classmethod
    def get_watch(cls, user):
        ukey = ndb.Key(User, user.get_id())
        qry = UserWatch.query(UserWatch.userkey == ukey)
        return qry
